#include <common/buffer.h>
#include <common/scopedlock.h>
#include <common/commoncrc.h>
#include "statesave.h"
#include "../lockablestorage.h"


const uint16_t StateSave::addr_ = 1020;


StateSave::StateSave(LockableStorage *storage)
	: storage_(storage)
	, read_(false)
	, id_(-1)
	, index_(-1)
{}

int StateSave::getId() {
	read();
	return id_;
}

void StateSave::setId(int id) {
	if (id_ != id) {
		id_ = id;
		write();
	}
}

int StateSave::getWptIndex() {
	read();
	return index_;
}

void StateSave::setWptIndex(int index) {
	if (index_ != index) {
		index_ = index;
		write();
	}
}

void StateSave::read() {
	if (read_)
		return;

	uint8_t data[4] = {0};

	id_ = -1;
	index_ = -1;	
	
	ScopedLock<LockableStorage> lock(storage_);
	if (!storage_->read(addr_, data, sizeof(data)))
		return;

	if (crc::Crc8().calc(data, 3) != data[3])
		return;
	
	Buffer buf(data, sizeof(data) - 1);
	id_ = buf.getUint8();
	index_ = buf.getUint16();
	
	read_ = true;
}

void StateSave::write() {
	uint8_t data[4] = {0};
	
	Buffer buf(data, sizeof(data));
	buf.putUint8(id_ > 0 ? static_cast<uint8_t>(id_) : 0);
	buf.putUint16(index_ > 0 ? static_cast<uint16_t>(index_) : 0);
	buf.putUint8(crc::Crc8().calc(data, 3));

	ScopedLock<LockableStorage> lock(storage_);
	storage_->write(addr_, data, buf.getIndexForPut());
	
	read_ = false;
}
